.TH std::atomic_flag 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::atomic_flag \- std::atomic_flag

.SH Synopsis
   Defined in header <atomic>
   class atomic_flag;          \fI(since C++11)\fP

   std::atomic_flag is an atomic boolean type. Unlike all specializations of
   std::atomic, it is guaranteed to be lock-free. Unlike std::atomic<bool>,
   std::atomic_flag does not provide load or store operations.

.SH Member functions

   constructor   constructs an atomic_flag
                 \fI(public member function)\fP
   operator=     the assignment operator (deleted)
   [deleted]     \fI(public member function)\fP
   clear         atomically sets flag to false
                 \fI(public member function)\fP
   test_and_set  atomically sets the flag to true and obtains its previous value
                 \fI(public member function)\fP
   test          atomically returns the value of the flag
   (C++20)       \fI(public member function)\fP
   wait          blocks the thread until notified and the atomic value changes
   (C++20)       \fI(public member function)\fP
   notify_one    notifies at least one thread waiting on the atomic object
   (C++20)       \fI(public member function)\fP
   notify_all    notifies all threads blocked waiting on the atomic object
   (C++20)       \fI(public member function)\fP

.SH Example

   A spinlock mutex demo can be implemented in userspace using an atomic_flag. Do note
   that spinlock mutexes are extremely dubious in practice.


// Run this code

 #include <atomic>
 #include <iostream>
 #include <thread>
 #include <vector>

 std::atomic_flag lock = ATOMIC_FLAG_INIT;

 void f(int n)
 {
     for (int cnt = 0; cnt < 40; ++cnt)
     {
         while (lock.test_and_set(std::memory_order_acquire)) // acquire lock
         {
             // Since C++20, it is possible to update atomic_flag's
             // value only when there is a chance to acquire the lock.
             // See also: https://stackoverflow.com/questions/62318642
         #if defined(__cpp_lib_atomic_flag_test)
             while (lock.test(std::memory_order_relaxed)) // test lock
         #endif
                 ; // spin
         }
         static int out{};
         std::cout << n << ((++out % 40) == 0 ? '\\n' : ' ');
         lock.clear(std::memory_order_release); // release lock
     }
 }

 int main()
 {
     std::vector<std::thread> v;
     for (int n = 0; n < 10; ++n)
         v.emplace_back(f, n);
     for (auto& t : v)
         t.join();
 }

.SH Possible output:

 0 1 1 2 0 1 3 2 3 2 0 1 2 3 2 3 0 1 3 2 0 1 2 3 2 3 0 3 2 3 2 3 2 3 1 2 3 0 1 3
 2 3 2 0 1 2 3 0 1 2 3 2 0 1 2 3 0 1 2 3 2 3 2 3 2 0 1 2 3 2 3 0 1 3 2 3 0 2 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 3 2 0 2 3 2 3 2 3 2 3 2 3 0 3
 2 3 0 3 0 3 2 3 0 3 2 3 2 3 0 2 3 0 3 2 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9

.SH See also

   atomic_flag_test_and_set          atomically sets the flag to true and returns its
   atomic_flag_test_and_set_explicit previous value
   \fI(C++11)\fP                           \fI(function)\fP
   \fI(C++11)\fP
   atomic_flag_clear
   atomic_flag_clear_explicit        atomically sets the value of the flag to false
   \fI(C++11)\fP                           \fI(function)\fP
   \fI(C++11)\fP
   atomic_flag_wait                  blocks the thread until notified and the flag
   atomic_flag_wait_explicit         changes
   (C++20)                           \fI(function)\fP
   (C++20)
   atomic_flag_notify_one            notifies a thread blocked in atomic_flag_wait
   (C++20)                           \fI(function)\fP
   atomic_flag_notify_all            notifies all threads blocked in atomic_flag_wait
   (C++20)                           \fI(function)\fP
   ATOMIC_FLAG_INIT                  initializes an std::atomic_flag to false
   \fI(C++11)\fP                           (macro constant)
   C documentation for
   atomic_flag
